#include "datapackage.h"
#include <QMetaType>

DataPackAge::DataPackAge()
{
    qRegisterMetaType<DataPackAge>("DataPackAge");
    this->timeStmp = "";
    this->data_length = 0;
    this->package_type = 0;
}

void DataPackAge::setDataLength(int data_length)
{
    this->data_length = data_length;
}

void DataPackAge::setTimeStamp(QString timeStamp)
{
    this->timeStmp = timeStamp;
}

void DataPackAge::setPointer(const u_char *pkt_content, int size)
{
    this->pkt_content =(u_char *)malloc(size);
    memcpy((char*)(this->pkt_content), pkt_content, size);
}

void DataPackAge::setInfo(QString info)
{
    this->info = info;
}

QString DataPackAge::getDataLength()
{
    return QString::number(this->data_length);
}

QString DataPackAge::getTimeStamp()
{
    return timeStmp;

}

QString DataPackAge::getPackageType()
{
    switch (this->package_type) {
    case 1: return "ARP";
    case 2: return "ICMP";
    case 3: return "TCP";
    case 4: return "UDP";
    case 5: return "DNS";
    case 6: return "TLS";
    case 7: return "SSL";
    default:
        return "";
    }
}

QString DataPackAge::getInfo()
{
    return this->info;
}

QString DataPackAge::byteToString(u_char *str, int size)
{
    QString res ="";
    for(int i = 0; i<size; i++)
    {
        char one = str[i]>>4;
        if(one >=0x0A)
        {
            one+=0x41 - 0x0A;
        }
        else
        {
            one += 0x30;
        }
        char two = str[i] & 0xF;
        if(two >=0x0A)
        {
            two+=0x41 - 0x0A;
        }
        else
        {
            two += 0x30;
        }
        res.append(one);
        res.append(two);
    }
    return res;
}

QString DataPackAge::getSource()
{
    if(this->package_type == 1)
    {
        return this->getSrcMacAddr();
    }
    else
    {
        return this->getSrcIpAddr();
    }
}

QString DataPackAge::getDestination()
{
    if(this->package_type == 1)
    {
        return this->getDesMacAddr();
    }
    else
    {
        return this->getDesIpAddr();
    }
}

QString DataPackAge::getDesMacAddr()
{
    ETHER_HEADER *eth;
    eth = (ETHER_HEADER *)(pkt_content);
    u_char *addr = eth->ethernet_des_host;

    if(addr)
    {
        QString res = byteToString(addr, 1) + "."
                      +byteToString((addr+1), 1) + "."
                      +byteToString((addr+2), 1) + "."
                      +byteToString((addr+3), 1) + "."
                      +byteToString((addr+4), 1) + "."
                      +byteToString((addr+5), 1);

        if(res == "FF:FF:FF:FF:FF:FF")
        {
            return "FF:FF:FF:FF:FF:FF(Broadcast)";
        }
        else
        {
            return res;
        }
    }
}

QString DataPackAge::getSrcMacAddr()
{
    ETHER_HEADER *eth;
    eth = (ETHER_HEADER *)(pkt_content);
    u_char *addr = eth->ethernet_src_host;

    if(addr)
    {
        QString res = byteToString(addr, 1) + "."
                      +byteToString((addr+1), 1) + "."
                      +byteToString((addr+2), 1) + "."
                      +byteToString((addr+3), 1) + "."
                      +byteToString((addr+4), 1) + "."
                      +byteToString((addr+5), 1);

        if(res == "FF:FF:FF:FF:FF:FF")
        {
            return "FF:FF:FF:FF:FF:FF(Broadcast)";
        }
        else
        {
            return res;
        }
    }

}

QString DataPackAge::getDesIpAddr()
{
    IP_HEADER *ip;
    ip=(IP_HEADER*)(pkt_content + 14);
    sockaddr_in desAddr;
    desAddr.sin_addr.s_addr = ip->des_addr;
    return QString(inet_ntoa(desAddr.sin_addr));
}

QString DataPackAge::getSrcIpAddr()
{
    IP_HEADER *ip;
    ip=(IP_HEADER*)(pkt_content + 14);
    sockaddr_in dsrcAddr;
    dsrcAddr.sin_addr.s_addr = ip->src_addr;
    return QString(inet_ntoa(dsrcAddr.sin_addr));
}

QString DataPackAge::getMacType()
{
    ETHER_HEADER *eth;
    eth = (ETHER_HEADER *)(pkt_content);

    u_short type  = ntohs(eth->type);

    if(type == 0x0800)
    {
        return "IPv4(0x0800)";
    }
    else if(0x806)
    {
        return "ARP(0x0806)";
    }
    else return "";
}

void DataPackAge::setPackageType(int type)
{
    this->package_type = type;
}
